/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dmcn.bl.genetics.fitnessfunction;

import dmcn.bl.genetics.genes.Concetrator;
import java.util.Random;
import javax.naming.spi.DirStateFactory;
import org.jgap.FitnessFunction;
import org.jgap.Gene;
import org.jgap.IChromosome;
import org.jgap.impl.IntegerGene;

/**
 *
 * @author Home
 */
public class AssignTerminalFitnessFunction extends FitnessFunction {

    private int numOfConcetrators;
    private int numOfTerminals;
    private Concetrator[] concetrators;
    private int sumAssign;
    private int sumFortio;

    public AssignTerminalFitnessFunction(int numOfConcetrators, int numOfTerminals) {
        this.numOfConcetrators = numOfConcetrators;
        this.numOfTerminals = numOfTerminals;
        //this.concetrators = concetrators;
    }

    @Override
    protected double evaluate(IChromosome ic) {

        Integer cost[][] =calculateCost(numOfConcetrators, numOfTerminals);
//        int cost[][] = {{2165, 1256}, {4236, 2456}, {6325, 4127}, {1234, 5462}, {7452, 4112}, {9652, 4586}};

//        Integer fortio[] = {1234, 150, 256, 456, 512, 987};
        Integer fortio[] = calculatefortio(numOfTerminals);
//        Integer xwritikothta[] = {2048, 2048};
        Integer xwritikothta[] = calculateXwritikotita(numOfConcetrators);
        double fitness = 0D;
        Gene[] genes = ic.getGenes();
        if (restriction1(numOfConcetrators, numOfTerminals, ic.getGenes())==true &&
            restriction2(numOfTerminals, numOfConcetrators, ic.getGenes(), fortio, xwritikothta)==true) {

            for (int i = 0; i < numOfTerminals; i++) {
//            sumAssign = 0;
//            sumFortio = 0;
                for (int j = 0; j < numOfConcetrators; j++) {

//                sumAssign = sumAssign + (Integer) genes[i * numOfConcetrators + j].getAllele();

//                if (sumAssign > 1) {
//                    break;
//                }
                    fitness = fitness + (cost[i][j] * ((Integer) genes[i * numOfConcetrators + j].getAllele()));
                }
            }
        }
        return fitness;

    }

    public static boolean restriction1(int numOfConcetrators, int numOfTerminals, Gene[] solution) {
        int sum;
        
        for (int i = 0; i < numOfTerminals; i++) {
            sum = 0;
            for (int j = 0; j < numOfConcetrators; j++) {
                sum = sum + (Integer) solution[i * numOfConcetrators + j].getAllele();
                if (sum > 1) {
                    return false;
                }
            }
        }
        return true;
    }

    public static boolean restriction2(int numOfTerminals, int numOfConcetrators, Gene[] solution, Integer[] fortio, Integer[] xwritikothta) {
        int sunolikoFortio;
        for (int j = 0; j < numOfConcetrators; j++) {
            sunolikoFortio = 0;
            for (int i = 0; i < numOfTerminals; i++) {
                sunolikoFortio = sunolikoFortio + ((Integer) solution[i * numOfConcetrators + j].getAllele() * fortio[i]);
            }
            //if (sunolikoFortio > xwritikothta[j]) {
            if (sunolikoFortio > xwritikothta[j]) {
                return false;
            }
        }
        return true;
    }

    private Integer[][] calculateCost(int numOfConcetrators, int numOfTerminals) {
        Random rand = new Random();
        Integer[][] costResult = new Integer[numOfTerminals][numOfConcetrators];
        for (int i = 0; i < numOfTerminals; i++) {
            for (int j = 0; j < numOfConcetrators; j++) {
                costResult[i][j] = rand.nextInt(1000);
            }
        }
        return costResult;
    }
    private Integer[] calculatefortio( int numOfTerminals) {
        Random rand = new Random();
        Integer[] fortioResult = new Integer[numOfTerminals];

            for (int j = 0; j < numOfTerminals; j++) {
                fortioResult[j] = rand.nextInt(300);
            }

        return fortioResult;
    }
    private Integer[] calculateXwritikotita(int numOfConcetrators) {
        Random rand = new Random();
        Integer[] xwritikotitaResult = new Integer[numOfConcetrators];
        for (int i = 0; i < numOfConcetrators; i++) {

                xwritikotitaResult[i] = rand.nextInt(5000);

        }
        return xwritikotitaResult;
    }
}
